#include <stdlib.h>
#include <stdio.h>

#ifndef __DLX_H
#define __DLX_H

typedef struct Node_S
{
  struct Node_S * U;
  struct Node_S * D;
  struct Node_S * L;
  struct Node_S * R;
  struct Node_S * C;
  int row, column, size;
} Node_T;
typedef Node_T * Node;

typedef struct SparseMatrix_S
{
  Node_T root;
  Node_T columnHead[4*GRID_SIZE*GRID_SIZE];
  Node   rowHead[GRID_SIZE*GRID_SIZE*GRID_SIZE];
  Node_T cells[4*GRID_SIZE*GRID_SIZE*GRID_SIZE];
} SparseMatrix_T;
typedef SparseMatrix_T * SparseMatrix;

inline void coverNode(Node c);
inline void uncoverNode(Node c);
void coverRow(Node n);
void uncoverRow(Node n);
void coverColumn(Node c);
void uncoverColumn(Node c);
void removeRow(SparseMatrix sm, int row);
inline int candidateToRow (int candidate, int row, int column);
void appendColumn (Node c, Node n);
SparseMatrix newSparseMatrix(void);
void delSparseMatrix(SparseMatrix sm);
void prtSparseMatrixRow(Node n);
void prtSparseMatrix(SparseMatrix sm);
void prtSearchSolution(Node O[]);
bool search(SparseMatrix sm, Node O[], int k);
bool dlx(SparseMatrix sm);

#define smIterateRows(i)    for (i = 0; i < GRID_SIZE*GRID_SIZE*GRID_SIZE; i++)
#define smIterateColumns(i) for (i = 0; i < 4*GRID_SIZE*GRID_SIZE;         i++)

#endif
